#include "CH58x_common.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "DevicesFlash.h"

/* 地址 需要是4的倍数 */
int8_t cFlashWriteDatas(uint32_t uiAddress, const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiData;
    int8_t cError = 0;

    if((uiAddress & 3) || (iLength < 1) || ((uiAddress + iLength) > FLASH_USER_MAX_ADDR))
    {
        printf("cFlashWriteDatas uiAddress: %08X iLength: %d >= FLASH_USER_MAX_ADDR.\r\n", uiAddress, iLength);
        return 1;
    }

    /* 每次写入4字节 */
    while(iLength > 0)
    {
        /* erase flash */
        if((uiAddress & (FLASH_PAGE_SIZE - 1)) == 0)
        {
            /* erase the flash pages */
            if(FLASH_ROM_ERASE(uiAddress, FLASH_PAGE_SIZE) != 0)
            {
                printf("cFlashWriteDatas FLASH_ErasePage addr: 0x%08X error.\r\n", uiAddress);
                return 2;
            }
        }

        /* read flash */
        if(EEPROM_READ(uiAddress, &uiData, sizeof(uiData)) != 0)
            return 3;

        /* program flash */
        if(memcmp(&uiData, pucDatas, iLength > 4 ? 4 : iLength) != 0)
        {
            memcpy(&uiData, pucDatas, iLength > 4 ? 4 : iLength);

            if(FLASH_ROM_WRITE(uiAddress, &uiData, 4) != 0)
                return 4;
        }

        uiAddress += 4;
        pucDatas += 4;;
        iLength -= 4;
    }

    return cError;
}

int8_t cFlashReadDatas(uint32_t uiAddress, void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = pvDatas;
    int32_t iLengthNow;
    uint8_t ucBuff[32];

    if((uiAddress & 3) || (iLength < 1) || ((uiAddress + iLength) > FLASH_USER_MAX_ADDR))
    {
        printf("cFlashReadDatas uiAddress: %08X iLength: %d >= FLASH_USER_MAX_ADDR.\r\n", uiAddress, iLength);
        return 1;
    }

    while(iLength > 0)
    {
        iLengthNow = iLength > sizeof(ucBuff) ? sizeof(ucBuff) : iLength;

        /* Read Flash */
        EEPROM_READ(uiAddress, ucBuff, sizeof(ucBuff));

        memcpy(pucDatas, ucBuff, iLengthNow);

        pucDatas += sizeof(ucBuff);
        iLength -= sizeof(ucBuff);
    }

    return 0;
}
